#!/usr/bin/perl

use DBI;
use strict;
use Cwd;

my $dsn="dbi:Pg:dbname=flux_monitoring;host=localhost;port=5432";
my $user="postgres";
my $password="";

# Set up a connection to the database listing the RPFITS files that need to be
# processed.
my $dbh=DBI->connect($dsn,$user,$password,{ RaiseError => 0, AutoCommit => 1});

# Query for all observations from the calibration table
my $toc_query="SELECT * FROM calibration WHERE ".
    "(primary1_processed=FALSE AND primary1_source IS NOT NULL) OR ".
    "(primary2_processed=FALSE AND primary2_source IS NOT NULL) OR ".
    "(primary3_processed=FALSE AND primary3_source IS NOT NULL) OR ".
    "(primary4_processed=FALSE AND primary4_source IS NOT NULL)";

my $toc=$dbh->prepare($toc_query);
$toc->execute;
my %calibration_row;
my @fields=qw(file source project obstime freq_if1 freq_if2
	      primary1_file primary1_source primary1_project primary1_time
	      primary2_file primary2_source primary2_project primary2_time
	      primary3_file primary3_source primary3_project primary3_time
	      primary4_file primary4_source primary4_project primary4_time
	      primary1_processed primary2_processed primary3_processed primary4_processed
	      bandpass_file bandpass_source bandpass_project bandpass_time);

while (@calibration_row{@fields}=$toc->fetchrow()){

    print "[main] found source calibrator file '".$calibration_row{'file'}."'\n\n";
    # start by loading the calibrator FITS file into miriad format
    # search for the full path of the file
    my ($full_path,$source_path)=&attach_path($calibration_row{'file'},$dbh);
    print "[main] converting source calibrator to miriad dataset...\n";
    &fits_to_miriad($full_path,$calibration_row{'freq_if1'});
    for (my $j=1;$j<=2;$j++){
	&rename_source($source_path,$calibration_row{'source'},
		       $calibration_row{"freq_if$j"},"source");
    }
    print "[main] source calibrator converted to miriad dataset\n\n";

    # get some information that we need for the database
    # the actual RA and Dec of the observation
    print "[main] obtaining RA & Dec of source calibrator...\n";
    my ($observed_ra,$observed_dec)=&get_ra_dec($source_path,
						"source",$calibration_row{'freq_if1'});
    print "[main] source calibrator RA=".$observed_ra." & Dec=".$observed_dec."\n\n";

    # which array was used for the observations?
    my $array_name;
    print "[main] determining array configuration for source calibrator observations...\n";
    my $gda_query="SELECT array_name FROM array_configurations ".
			  "WHERE start_date<'".$calibration_row{'obstime'}."' ".
			  "AND end_date>'".$calibration_row{'obstime'}."'";
    my $gda=$dbh->prepare($gda_query);
    $gda->execute;
    while (my @arrays=$gda->fetchrow()){
	$array_name=$arrays[0];
	print "[main] array configuration was ".$array_name." during source calibrator observations\n\n";
    }
    $gda->finish;
    
    # when was the last acal,dcal,pcal?
    print "[main] determining times of last calibrators...\n";
    my ($dcal_time,$pcal_time,$acal_time)=
	&get_cal_times($calibration_row{'obstime'},$calibration_row{'freq_if1'},
		       $calibration_row{'freq_if2'},$dbh);
    print "[main]     last delay cal was @ ".$dcal_time."\n";
    print "[main]     last phase cal was @ ".$pcal_time."\n";
    print "[main] last amplitude cal was @ ".$acal_time."\n\n";
    
    # extract the bandpass calibrator unless it is the same as the source
    my ($full_path,$calibrator_path)=&attach_path($calibration_row{'bandpass_file'},$dbh);
    if ($calibration_row{'bandpass_file'} ne $calibration_row{'file'}){
	print "[main] extracting bandpass calibrator file '".$calibration_row{'bandpass_file'}."'...\n";
	&fits_to_miriad($full_path,$calibration_row{'freq_if1'});
	for (my $j=1;$j<=2;$j++){
	    &rename_source($calibrator_path,$calibration_row{'bandpass_source'},
			   $calibration_row{"freq_if$j"},"source_bandpass");
	}
	print "[main] bandpass calibrator converted to miriad dataset\n\n";
    } else {
	print "[main] source calibrator will be used as bandpass calibrator\n\n";
    }
    
    # check for the primary calibrators - we know we have at least one since
    # the SQL query ensures that
    my $got_primary=0;
    my $primary_path;
    for (my $i=1;$i<=4;$i++){
	if (($calibration_row{"primary$i\_source"} ne "")&&
	    ($calibration_row{"primary$i\_processed"}==0)){
	    # extract this file
	    ($full_path,$primary_path)=&attach_path($calibration_row{"primary$i\_file"},$dbh);
	    if ($calibration_row{'bandpass_file'} ne $calibration_row{"primary$i\_file"}){
		# only extract the primary if it is different to the
		# bandpass calibrator
		print "[main] extracting primary calibrator file '".$calibration_row{"primary$i\_file"}.
		    "'...\n";
		&fits_to_miriad($full_path,$calibration_row{'freq_if1'});
		for (my $j=1;$j<=2;$j++){
		    &rename_source($primary_path,$calibration_row{"primary$i\_source"},
				   $calibration_row{"freq_if$j"},"primary");
		}
		print "[main] primary calibrator converted to miriad dataset\n\n";
	    } else {
		print "[main] the source bandpass calibrator will be used as primary calibrator\n\n";
	    }

	    # find out the bandpass calibrator for the primary flux calibrator
	    my ($pbandpass_file,$pbandpass_source)=
		&primary_bandpass($calibration_row{"primary$i\_file"},$dbh);
	    my ($full_path,$pbandpass_path)=&attach_path($pbandpass_file,$dbh);
	    if (($calibration_row{'bandpass_file'} ne $pbandpass_file)&&
		($calibration_row{"primary$i\_file"} ne $pbandpass_file)){
		# only extract the bandpass primary calibrator if it's not the source's
		# bandpass calibrator, or it's not the primary calibrator itself
		print "[main] extracting primary bandpass calibrator file '".
		    $pbandpass_file."'...\n";
		&fits_to_miriad($full_path,$calibration_row{'freq_if1'});
		for (my $j=1;$j<=2;$j++){
		    &rename_source($pbandpass_path,$pbandpass_source,
				   $calibration_row{"freq_if$j"},"primary_bandpass");
		}
		print "[main] bandpass calibrator for primary calibrator converted to miriad dataset\n\n";
	    } else {
		if ($calibration_row{'bandpass_file'} eq $pbandpass_file){
		    print "[main] the source bandpass calibrator will be used as primary bandpass calibrator\n\n";
		} elsif ($calibration_row{"primary$i\_file"} eq $pbandpass_file){
		    print "[main] the primary calibrator will be used as primary bandpass calibrator\n\n";
		}
	    }
	    # now loop over frequencies
	    for (my $j=1;$j<=2;$j++){
		my $flux_scale_factor;
		# step 5. MFCAL bandpass calibrator(s)
		if ($calibration_row{'bandpass_file'} ne $calibration_row{'file'}){
		    print "[main] calibrating source bandpass calibrator...\n";
		    &calibrate_source($calibrator_path,"source_bandpass",
				      $calibration_row{"freq_if$j"},1);
		    print "[main] source bandpass calibrated\n\n";
		} else {
		    print "[main] calibrating source calibrator...\n";
		    &calibrate_source($calibrator_path,"source",
				      $calibration_row{"freq_if$j"},1);
		    print "[main] source calibrated\n\n";
		}		    
		if ($pbandpass_file ne $calibration_row{'bandpass_file'}){
		    if ($pbandpass_file ne $calibration_row{"primary$i\_file"}){
			print "[main] calibrating primary bandpass calibrator...\n";
			&calibrate_source($pbandpass_path,"primary_bandpass",
					  $calibration_row{"freq_if$j"},1);
			print "[main] primary bandpass calibrated\n\n";
		    } else {
			print "[main] calibrating the primary calibrator...\n";
			&calibrate_source($primary_path,"primary",
					  $calibration_row{"freq_if$j"},1);
			print "[main] primary calibrated\n\n";
		    }
		} # otherwise we've already calibrated the bandpass calibrator

		# step 6. GPCOPY bandpass to primary flux cal and source
		# checking of course that the bandpass is not the source or
		# the primary
		if ($calibration_row{'bandpass_file'} ne $calibration_row{'file'}){
		    print "[main] copying bandpass to source...\n";
		    &calibration_copy($calibrator_path,"source_bandpass",
				      $calibration_row{"freq_if$j"},$source_path,
				      "source",$calibration_row{"freq_if$j"});
		    print "[main] source bandpass copied\n\n";
		}
		if ($pbandpass_file ne $calibration_row{"primary$i\_file"}){
#		if ($calibration_row{'bandpass_file'} ne $calibration_row{"primary$i\_file"}){
		    if ($pbandpass_file ne $calibration_row{'bandpass_file'}){
			print "[main] copying primary bandpass to primary calibrator...\n";
			&calibration_copy($pbandpass_path,"primary_bandpass",
					  $calibration_row{"freq_if$j"},$primary_path,
					  "primary",$calibration_row{"freq_if$j"});
			print "[main] primary bandpass copied\n\n";
		    } else {
			print "[main] copying bandpass to primary calibrator...\n";
			&calibration_copy($calibrator_path,"source_bandpass",
					  $calibration_row{"freq_if$j"},$primary_path,
					  "primary",$calibration_row{"freq_if$j"});
			print "[main] bandpass copied\n\n";
		    }
		}

		# step 7. MFCAL source
		if ($calibration_row{'bandpass_file'} ne $calibration_row{'file'}){
		    print "[main] calibrating source calibrator (sans bandpass)...\n";
		    &calibrate_source($source_path,"source",
				      $calibration_row{"freq_if$j"},0);
		    print "[main] source calibrated\n";
		}
		if (($calibration_row{"primary$i\_source"}!~/[Uu]ranus/)&&
		    ($calibration_row{"primary$i\_source"}!~/[Mm]ars/)){
		    # we're not dealing with a planet
		    # step 8. MFCAL primary flux calibrator (non-planet flux cals only)
		    if ($pbandpass_file ne $calibration_row{"primary$i\_file"}){
			print "[main] calibrating primary calibrator (sans bandpass)...\n";
			&calibrate_source($primary_path,"primary",
					  $calibration_row{"freq_if$j"},0);
			print "[main] primary calibrated\n";
		    }

		    # step 9. GPBOOT source from primary flux calibrator to set
		    # amplitude scale
		    print "[main] scaling source flux using non-planet primary calibrator...\n";
		    if ($calibration_row{'bandpass_file'} ne $calibration_row{"primary$i\_file"}){
			$flux_scale_factor=
			    &scale_gpboot($source_path,"source",
					  $calibration_row{"freq_if$j"},
					  $primary_path,"primary",
					  $calibration_row{"freq_if$j"});
		    } else {
			$flux_scale_factor=
			    &scale_gpboot($source_path,"source",
					  $calibration_row{"freq_if$j"},
					  $calibrator_path,"source_bandpass",
					  $calibration_row{"freq_if$j"});
		    }
		    print "[main] source flux scaling complete\n\n";
		    print "[main/debug] GPBOOT reports <$flux_scale_factor>\n\n";
		} else {
		    # a planet is the flux calibrator, so we need to do things in a 
		    # slightly different order
		    # step 10. MFBOOT source from primary flux calibrator to set
		    # amplitude scale
		    print "[main] scaling source flux using planet primary calibrator...\n";
		    $flux_scale_factor=
			&scale_mfboot($source_path,"source",
				      $calibration_row{"freq_if$j"},
				      $primary_path,"primary",
				      $calibration_row{"freq_if$j"});
		    print "[main] source flux scaling complete\n\n";
		}

		# step 11. CALRED source to get flux
		print "[main] measuring source flux...\n";
		my ($scalar_flux,$vector_flux)=&measure_flux($source_path,
							     "source",
							     $calibration_row{"freq_if$j"});
		print "[main] source flux measured\n\n";
		# and the closure phase for some quality information
		print "[main] measuring closure phase...\n";
		my ($actual_phase,$theoretical_phase)=
		    &measure_closure_phase($source_path,"source",
					   $calibration_row{"freq_if$j"});
		print "[main] closure phase measured\n\n";

		# some other info we need for the database
		# information about the last pointing performed
		print "[main] getting information about last pointing...\n";
		my ($lastpoint_time,$lastpoint_source,$lastpoint_az,$lastpoint_el)=
		    &get_pointing_info($calibration_row{'file'},$dbh);
		print "[main] last pointing information obtained\n\n";

		# information about where the telescope was pointing
		print "[main] getting information about telescope position during observations...\n";
		my ($source_az,$source_el)=&get_az_el($source_path,"source",
						      $calibration_row{"freq_if$j"});
		my ($primary_az,$primary_el);
		if ($calibration_row{'bandpass_file'} ne $calibration_row{"primary$i\_file"}){
		    ($primary_az,$primary_el)=&get_az_el($primary_path,"primary",
							 $calibration_row{"freq_if$j"});
		} else {
		    ($primary_az,$primary_el)=&get_az_el($primary_path,"bandpass",
							 $calibration_row{"freq_if$j"});
		}
		print "[main] information about telescope position obtained\n\n";
		
		# OK we're ready to enter the information into the database
		print "[main] entering information into flux database...\n";
		my $enf_query="INSERT INTO fluxes VALUES (NEXTVAL('fluxes_entry_num_seq'),'".$calibration_row{'source'}."','".
		    $calibration_row{'obstime'}."','".$calibration_row{'project'}."',".
		    $calibration_row{"freq_if$j"}.",'".$calibration_row{"primary$i\_source"}."','".
		    $calibration_row{"primary$i\_project"}."',TIMESTAMP '".$calibration_row{'obstime'}."'- TIMESTAMP '".
		    $calibration_row{"primary$i\_time"}."',".$i.",'".$observed_ra."','".$observed_dec."','".
		    $array_name."',".$actual_phase.",".$theoretical_phase.",".$flux_scale_factor.",".
		    $scalar_flux.",".$vector_flux.",'".$calibration_row{'bandpass_source'}."','".
		    $calibration_row{'bandpass_project'}."',TIMESTAMP '".$calibration_row{'obstime'}."'- TIMESTAMP '".
		    $calibration_row{'bandpass_time'}."','".$lastpoint_source."',TIMESTAMP '".$calibration_row{'obstime'}.
		    "'- TIMESTAMP '".$lastpoint_time."',".$lastpoint_az.",".$lastpoint_el.",".$source_az.",".$source_el.",".
		    $primary_az.",".$primary_el.",TIMESTAMP '".$calibration_row{'obstime'}."'- TIMESTAMP '".$acal_time."',".
		    "TIMESTAMP '".$calibration_row{'obstime'}."'- TIMESTAMP '".$pcal_time."',TIMESTAMP '".
		    $calibration_row{'obstime'}."'- TIMESTAMP '".$dcal_time."'".
		    ")";
		print "[main/debug] executing query $enf_query\n";
		my $enf=$dbh->prepare($enf_query);
		$enf->execute;
		$enf->finish;
		print "[main] information entered into flux database\n\n";
		
		# delete the primary file, unless it is also our bandpass calibrator
		if ($calibrator_path ne $primary_path){
		    print "[main] deleting primary dataset at frequency ".
			$calibration_row{"freq_if$j"}."...\n";
		    &delete_files($calibration_row{"freq_if$j"},-1,$primary_path,
				  "primary");
		    print "[main] primary dataset deleted\n\n";
		    if ($calibration_row{'bandpass_file'} ne $pbandpass_file){
			print "[main] deleting primary bandpass dataset at frequency ".
			    $calibration_row{"freq_if$j"}."...\n";
			&delete_files($calibration_row{"freq_if$j"},-1,$pbandpass_path,
				      "primary_bandpass");
			print "[main] primary bandpass dataset deleted\n\n";
		    }
		}
	    }
	    # set the primary as processed
	    print "[main] flagging source as calibrated using primary number ".$i."...\n";
	    my $prp_query="UPDATE calibration SET primary$i\_processed=TRUE WHERE ".
		"primary$i\_file='".$calibration_row{"primary$i\_file"}."'";
	    # print "executing query $prp_query\n";
	    my $prp=$dbh->prepare($prp_query);
	    $prp->execute;
	    $prp->finish;
	    print "[main] source flagged as calibrated\n\n";
	}
    }
    
    # delete all the files we've just made
    print "[main] deleting source and bandpass calibrator datasets...\n";
    &delete_files($calibration_row{'freq_if1'},$calibration_row{'freq_if2'},$source_path,
		  "source");
    &delete_files($calibration_row{'freq_if1'},$calibration_row{'freq_if2'},$calibrator_path,
		  "source_bandpass");
    print "[main] source and bandpass datasets deleted\n\n";

    # this exit is here for debugging purposes
    # REMOVE WHEN DEBUGGING IS NOT NEEDED!
#    exit;
}

$toc->finish;

sub primary_bandpass {
    my ($primary_file,$dbh)=@_;

    my $gbf_query="SELECT bandpass_file,bandpass_source FROM calibration WHERE file='".$primary_file."'";
#    print "executing $gbf_query\n";
    my $gbf=$dbh->prepare($gbf_query);
    my $nres=$gbf->execute;
    my $bandpass_file;
    my $bandpass_source;
    print " [primary_bandpass/debug] found $nres possible primary bandpass sources\n";
    if ($nres==1){
	($bandpass_file,$bandpass_source)=$gbf->fetchrow();
	print " [primary_bandpass/debug] found primary bandpass $bandpass_file ($bandpass_source)\n";
    }
    $gbf->finish;

    return ($bandpass_file,$bandpass_source);
}

sub delete_files {
    my ($freq1,$freq2,$source_path,$source_name)=@_;

    my $delete_command;

    if ($freq1!=-1){
	$delete_command="rm -rf ".$source_path."/".$source_name.".".$freq1;
	&execute_command($delete_command);
    }
    if ($freq2!=-1){
	$delete_command="rm -rf ".$source_path."/".$source_name.".".$freq2;
	&execute_command($delete_command);
    }
}

sub get_cal_times {
    my ($source_time,$freq1,$freq2,$dbh)=@_;
    
    my ($dcal_time,$pcal_time,$acal_time);
    
    for (my $i=0;$i<3;$i++){
	my $ctg_query="SELECT * FROM events WHERE event_time<'".$source_time."' ".
	    "AND (if1_freq=".$freq1." AND if2_freq=".$freq2.") AND ";
	if ($i==0){
	    print " [get_cal_times/debug] searching for delay cal events...\n";
	    $ctg_query.="(event_type='dcal') ";
	} elsif ($i==1){
	    print " [get_cal_times/debug] searching for phase cal events...\n";
	    $ctg_query.="(event_type='pcal') ";
	} elsif ($i==2){
	    print " [get_cal_times/debug] searching for amplitude cal events...\n";
	    $ctg_query.="(event_type='acal' OR event_type='paddle') ";
	}
	$ctg_query.="ORDER BY event_time DESC LIMIT 1";
	my $ctg=$dbh->prepare($ctg_query);
	my $ngot=$ctg->execute;
	if ($ngot==1){
	    my @els=$ctg->fetchrow();
	    if ($i==0){
		$dcal_time=$els[1];
		print " [get_cal_times/debug] time: $dcal_time\n";
	    } elsif ($i==1){
		$pcal_time=$els[1];
		print " [get_cal_times/debug] time: $pcal_time\n";
	    } elsif ($i==2){
		$acal_time=$els[1];
		print " [get_cal_times/debug] time: $acal_time\n";
	    }
	}
	$ctg->finish;
    }

    return ($dcal_time,$pcal_time,$acal_time);
}

sub get_az_el {
    my ($path,$source,$freq)=@_;
    my $miriad_command;
    my $varlogfile="vars.log";

    $path=&shrink_path($path);
    $miriad_command="uvlist ";
    $miriad_command.="vis=".$path."/".$source.".".$freq;
    $miriad_command.=" options=var,full ";
    $miriad_command.="log=".$varlogfile;

    &execute_command("rm -f ".$varlogfile);
    &execute_command($miriad_command);

    open(VARS,$varlogfile);
    my $observed_az;
    my $observed_el;
    while(<VARS>){
	chomp;
	my @els=split(/\s+/);
	for (my $i=0;$i<=$#els;$i++){
	    if ($els[$i] eq "antaz"){
		$observed_az=$els[$i+2];
	    } elsif ($els[$i] eq "antel"){
		$observed_el=$els[$i+2];
	    }
	}
    }
    close(VARS);

    &execute_command("rm -f ".$varlogfile);

    return ($observed_az,$observed_el);
}

sub get_ra_dec {
    my ($path,$source,$freq)=@_;
    my $miriad_command;

    $path=&shrink_path($path);
    $miriad_command="uvindex ";
    $miriad_command.="vis=".$path."/".$source.".".$freq;
    
    my @cmd_result;
    my $observed_ra;
    my $observed_dec;
    @cmd_result=&execute_command($miriad_command);
    my $next_line=0;
    for (my $i=0;$i<=$#cmd_result;$i++){
	if ($next_line==1){
	    my @els=split(/\s+/,$cmd_result[$i]);
	    $observed_ra=$els[2];
	    $observed_dec=$els[3];
	    $next_line=0;
	} elsif ($cmd_result[$i]=~/^\sSource/){
	    $next_line=1;
	}
    }
    
    return($observed_ra,$observed_dec);
}

sub measure_closure_phase {
    my ($path,$source,$freq)=@_;
    my $miriad_command;

    $path=&shrink_path($path);
    $miriad_command="closure ";
    $miriad_command.="vis=".$path."/".$source.".".$freq." ";
    $miriad_command.="stokes=i ";
    $miriad_command.="device=/null";

    my @cmd_result;
    my $theoretical_phase;
    my $actual_phase;
    @cmd_result=&execute_command($miriad_command);
    for (my $i=0;$i<=$#cmd_result;$i++){
	if ($cmd_result[$i]=~/^Actual\sclosure/){
	    my @els=split(/\s+/,$cmd_result[$i]);
	    $actual_phase=$els[$#els];
	} elsif ($cmd_result[$i]=~/^Theoretical\sclosure/){
	    my @els=split(/\s+/,$cmd_result[$i]);
	    $theoretical_phase=$els[$#els];
	}
    }

    return($actual_phase,$theoretical_phase);
}

sub measure_flux {
    my ($path,$source,$freq)=@_;
    my $miriad_command;

    $path=&shrink_path($path);
    $miriad_command="calred ";
    $miriad_command.="vis=".$path."/".$source.".".$freq." ";
    $miriad_command.="stokes=i ";
    $miriad_command.="interval=1000";

    my @cmd_result;
    my $vector_flux;
    my $scalar_flux;
    @cmd_result=&execute_command($miriad_command);
    my $next_line=0;
    for (my $i=0;$i<=$#cmd_result;$i++){
	if ($next_line==1){
	    my @els=split(/\s+/,$cmd_result[$i]);
	    $scalar_flux=$els[1];
	    $vector_flux=$els[2];
	    $next_line=0;
	} elsif ($cmd_result[$i]=~/^Source\s/){
	    $next_line=1;
	}
    }
    return ($scalar_flux,$vector_flux);
}

sub scale_gpboot {
    my ($source_path,$source,$source_freq,$cal_path,$cal,$cal_freq)=@_;
    my $miriad_command;

    $source_path=&shrink_path($source_path);
    $cal_path=&shrink_path($cal_path);
    $miriad_command="gpboot ";
    $miriad_command.="vis=".$source_path."/".$source.".".$source_freq." ";
    $miriad_command.="cal=".$cal_path."/".$cal.".".$cal_freq;

    my @cmd_result;
    my $flux_scale_factor;
    @cmd_result=&execute_command($miriad_command);
    for (my $i=0;$i<=$#cmd_result;$i++){
#	print "GPBOOT output: <$cmd_result[$i]>\n";
	if ($cmd_result[$i]=~/^Secondary flux density scaled by\:/){
	    my @els=split(/\s+/,$cmd_result[$i]);
	    $flux_scale_factor=$els[$#els];
	}
    }
    
    return $flux_scale_factor;
}

sub scale_mfboot {
    my ($source_path,$source,$source_freq,$cal_path,$cal,$cal_freq)=@_;
    my $miriad_command;

    $source_path=&shrink_path($source_path);
    $cal_path=&shrink_path($cal_path);
    $miriad_command="mfboot ";
    $miriad_command.="vis=".$cal_path."/".$cal.".".$cal_freq.",".
	$source_path."/".$source.".".$source_freq." ";
    $miriad_command.="\"select=source($cal)\" ";
    $miriad_command.="clip=0.3 device=/null";

    my @cmd_result;
    my $flux_scale_factor;
    @cmd_result=&execute_command($miriad_command);
    for (my $i=0;$i<=$#cmd_result;$i++){
#	print "$cmd_result[$i]\n";
	if ($cmd_result[$i]=~/^Scaling the data by/){
	    my @els=split(/\s+/,$cmd_result[$i]);
	    $flux_scale_factor=$els[$#els];
#	    print "fsf = $flux_scale_factor\n";
	}
    }
    
    return ($flux_scale_factor);
}

sub calibration_copy {
    my ($in_path,$in_source,$in_freq,$out_path,$out_source,$out_freq)=@_;
    my $miriad_command;

    $in_path=&shrink_path($in_path);
    $out_path=&shrink_path($out_path);
    $miriad_command="gpcopy ";
    $miriad_command.="vis=".$in_path."/".$in_source.
	".".$in_freq." ";
    $miriad_command.="out=".$out_path."/".$out_source.".".
	$out_freq;

    &execute_command($miriad_command);
    
}

sub calibrate_source {
    my ($path,$source,$freq,$bpflag)=@_;
    my $miriad_command;

    $path=&shrink_path($path);
    # start with an mfcal
    $miriad_command="mfcal ";
    $miriad_command.="vis=".$path."/".$source.".".$freq." ";
    $miriad_command.="interval=0.1";
    if ($bpflag==0){
	# this is not the bandpass calibrator
	$miriad_command.=" options=nopassol";
    }
    
    &execute_command($miriad_command);

#    # then a gpcal
#    $miriad_command="gpcal ";
#    $miriad_command.="vis=".$path."/".$source.".".$freq." ";
#    $miriad_command.="interval=0.1";
    
#    &execute_command($miriad_command);
}

sub shrink_path {
    my $full_path=$_[0];

    my $currdir=getcwd;
    my @eldir=split(/\/+/,$currdir);
    for (my $i=1;$i<=$#eldir;$i++){
	if ($full_path=~/^\/$eldir[$i].*/){
	    $full_path=~s/^\/$eldir[$i]//;
	} else {
	    $full_path="..".$full_path;
	}
    }
    
    if (($full_path!~/^\/.*\/.*/)&&
	($full_path!~/^\.\.\/.*/)){
	$full_path=".".$full_path;
    }

    return $full_path;
}

sub fits_to_miriad {
    my $full_path=$_[0];
    my $frequency=$_[1];

    my $miriad_command;
    $full_path=&shrink_path($full_path);

    # get the base of the filename
    my $filepart=$full_path;
    $filepart=~s/(.*)\.(.*)$/$1/;

    # step 1. ATLOD
    $miriad_command="atlod ";
    $miriad_command.="in=".$full_path." ";
    $miriad_command.="out=".$filepart.".uv ";
    # an aside - check that the outfile doesn't exist
    if (-e $filepart.".uv"){
	# it does exist, remove it
	system "rm -rf $filepart.uv";
    }
    # now we attach options based on frequency
    if ($frequency>15000){
	$miriad_command.="options=opcorr";
    }
    
    &execute_command($miriad_command);
    
    # step 2. UVFLAG
    $miriad_command="uvflag ";
    $miriad_command.="vis=".$filepart.".uv ";
    $miriad_command.="flagval=flag ";

    &execute_command($miriad_command."select=auto");
    &execute_command($miriad_command."edge=100");
    my @bad_channels=(641,257,769,1409,1281,1921,1793,1177,157);
    for (my $i=0;$i<=$#bad_channels;$i++){
	&execute_command($miriad_command."line=chan,1,".$bad_channels[$i]);
    }

    # step 3. ATFIX (3mm data only)
    if ($frequency>70000){
	$miriad_command="atfix ";
	$miriad_command.="vis=".$filepart.".uv ";
	$miriad_command.="out=".$filepart.".fix.uv ";
	$miriad_command.="tsyscal=any";
	&execute_command($miriad_command);
	&execute_command("rm -rf ".$filepart.".uv");
	&execute_command("mv ".$filepart.".fix.uv ".$filepart.".uv");
    }

    # step 4. UVSPLIT
    $miriad_command="uvsplit ";
    $miriad_command.="vis=".$filepart.".uv ";
    $miriad_command.="options=clobber";

    &execute_command($miriad_command);

    # now we can delete the UV file
    &execute_command("rm -rf ".$filepart.".uv");
}

sub attach_path {
    my $file_needed=$_[0];
    my $dbh=$_[1];
    
    my $full_path;
    my $path_only;
    
    my $gef=$dbh->prepare("SELECT file,path FROM extracted_files WHERE ".
			  "file='".$file_needed."'");
    $gef->execute;
    while (my ($extracted_file,$extracted_path)=$gef->fetchrow()){
	$full_path=$extracted_path."/".$extracted_file;
	$path_only=$extracted_path;
    }
    $gef->finish;
    return ($full_path,$path_only);
}

sub get_pointing_info {
    my $file_needed=$_[0];
    my $dbh=$_[1];

    my ($got_file,$pointing_time,$pointing_source,$pointing_az,$pointing_el);

    my $gpi_query="SELECT file,last_pointing_time,last_pointing_source,".
	"last_pointing_az,last_pointing_el FROM extracted_files WHERE ".
	"file='".$file_needed."'";
    my $gpi=$dbh->prepare($gpi_query);
    $gpi->execute;
    ($got_file,$pointing_time,$pointing_source,$pointing_az,$pointing_el)=
	$gpi->fetchrow();
    $gpi->finish;
    return ($pointing_time,$pointing_source,$pointing_az,$pointing_el);
}

sub rename_source {
    my ($path,$source_name,$frequency,$type)=@_;
    
    my $rename_command="mv ";
    $rename_command .= $path."/".$source_name.".".$frequency." ";
    $rename_command .= $path."/".$type.".".$frequency;

    execute_command($rename_command);

}

sub execute_command {
    my $command_to_execute=$_[0];
    
#    print "executing command <".$command_to_execute.">\n";
    print "  [execute_command] executing command <".$command_to_execute.">\n";
    my @cmnd_result;
    open(CMND,"-|")||exec $command_to_execute;
    while(<CMND>){
	chomp;
	my $line=$_;
#	print "COMMAND output: <$line>\n";
	push @cmnd_result,$line;
    }
    close(CMND);

    return @cmnd_result;
}
